跳到主要内容

结构模式-装饰器模式

装饰模式是什么?

装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。

classDiagram Component <|-- ConcreteComponent Component <|-- Decorator Decorator o--> Component Decorator <|-- ConcreteDecoratorA Decorator <|-- ConcreteDecoratorB Component: +operation() Component: <<abstract>> ConcreteComponent: +operation() Decorator: <<abstract>> Decorator: +operation() ConcreteDecoratorA: -addedState string ConcreteDecoratorA: +operation() ConcreteDecoratorB: -addedBehavior() ConcreteDecoratorB: +operation()

实际上就是像 JavaEE 的过滤器(Filter)那样,在执行目标方法之前经过一堆的过滤器,而这个装饰器实际作用就像过滤器那样在执行目标方法前执行一堆 “装饰” 的方法(不一定要放在前面,也可能放在后面)

  • Component 定义了一个对象接口,可以给这些对象动态的添加职责
  • ConcreteComponent 是定义了一个具体的对象(就是被装饰的对象)
  • Decorator 装饰抽象类

装饰器使用示例

创建一个 Component 接口,整个装饰模式的类都需要继承这个接口

public interface Component {
void operation();
}

具体需要被装饰的对象

public class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("具体被装饰的对象");
}
}

定义一个装饰器抽象类

public abstract class Decorator implements Component {
protected Component component;

public void setComponent(Component component) {
this.component = component;
}

@Override
public void operation() {
if (component != null) {
component.operation();
}
}
}

具体的装饰器

public class ConcreteDecoratorA extends Decorator {
private String addedState;

@Override
public void operation() {
super.operation();
addedState = "这是一个附加上去的状态"
System.out.println("当前状态是:" + addedState);
}
}


public class ConcreteDecoratorB extends Decorator {
private void addedBehavior() {
System.out.println("装饰的操作");
}

@Override
public void operation() {
// 可以在前面执行
addedBehavior();
super.operation();
}
}

使用这些装饰器去具体的装饰对象

public static void main(String[] args) {
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();

d1.setComponent(c);
d2.setComponent(d1);
d2.operation();
// 输出:----------------
// 装饰的操作
// 具体被装饰的对象
// 当前状态是:这是一个附加上去的状态
}

注意:实际上如果只有一个 ConcreteComponent 类则可以不用单独创建 Component 接口,直接让 Decorator 继承 ConcreteComponent 就行了